package com.k7k7.util;

import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * User: Administrator
 * Date: 2009-5-4
 * Time: 13:07:09
 */
public class EchoServer {
	private int port = 8000;
	private ServerSocket serverSocket;
	private ExecutorService executorService;
	private final int POOL_SIZE = 4;
	//
	private int portForShutdown = 8001;
	private ServerSocket serverSocketForShutdown;
	private boolean isShutdown = false;
	private Thread shutdownthread = new Thread() {
		@Override public void start() {
			this.setDaemon(true);
			super.start();
		}

		@Override public void run() {
			while (!isShutdown) {
				Socket socketForShutdown = null;
				try {
					socketForShutdown = serverSocketForShutdown.accept();
					BufferedReader br = new BufferedReader(new InputStreamReader(socketForShutdown.getInputStream()));
					String command = br.readLine();
					if (command.equals("shutdown")) {
						long beginTime = System.currentTimeMillis();
						socketForShutdown.getOutputStream().write("closing...".getBytes());
						isShutdown = true;
						executorService.shutdown();
						while (!executorService.isTerminated()) {
							executorService.awaitTermination(30, TimeUnit.SECONDS);
						}
						serverSocket.close();
						long endtime = System.currentTimeMillis();
						socketForShutdown.getOutputStream().write(("closed" + (endtime - beginTime) + "\n").getBytes());
						socketForShutdown.close();
						serverSocketForShutdown.close();
					} else {
						socketForShutdown.getOutputStream().write("wrong".getBytes());
						socketForShutdown.close();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	};

	public EchoServer() throws IOException {
		serverSocket = new ServerSocket(port);
		executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE);
		serverSocketForShutdown = new ServerSocket(portForShutdown);
		shutdownthread.start();
	}

	public void service() {
		while (!isShutdown) {
			Socket socket = null;
			try {
				socket = serverSocket.accept();
				executorService.execute(new Handler(socket));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) throws IOException {
		new EchoServer().service();
	}
}

class Handler implements Runnable {
	public Handler(Socket socket) {
	}

	@Override public void run() {
	}
}